package SGEngine

import (
//"github.com/gl"
)

func Layer(Index uint32) uint32 {
	return 1 << Index
}

type IRenderer interface {
	Render()
}

type INode interface {
	GetTransfrom() ITransfrom
	SetTransfrom(ITransfrom)
	Parent() INode
	SetParent(INode)
	Childrens() *ACArrayList

	GetRender() IRenderer
	GetLayer() uint32
	SetLayer(uint32)

	GetNode() *Node

	GetMe() interface{}

	RemoveChild(INode)
	DeleteNode(INode)
	RemoveChildAt(int)
	Destroy()
	_Destroy()

	GetRect(INode, Vec3, Vec3) *Rect
	AddCompnent(CompnentFunc) ICompnent
	GetCompnent(CompnentFunc) ICompnent
}

type Node struct {
	ITransfrom
	ParentNode    INode
	ChildrenNodes ACArrayList
	NodeLayer     uint32

	NodeRender IRenderer

	Me interface{}

	compnents map[string]ICompnent

	MGetRect GetRectFunc

	EventState int32

	Enable bool
}

func DefaultNode() Node {
	RNode := new(Node)
	BT := newBaseTransfrom()
	BT.Mnode = RNode
	BT.SetIsSizeScale(true)
	RNode.ITransfrom = BT
	RNode.SetSize(1, 1, 1)
	RNode.SetMat(Mat4Identity.Clone())
	RNode.MGetRect = node_GetRect
	RNode.Enable = true
	return *RNode
}

func node_GetRect(node INode, Scale Vec3, Postion Vec3) *Rect {
	r := new(Rect)
	T := node.GetTransfrom()
	SX, SY := Scale.X, Scale.Y
	PX, PY, _ := T.GetPosition()
	r.MinX = -T.Size().X*SX*0.5 + PX
	r.MaxX = T.Size().X*SX*0.5 + PX
	r.MinY = -T.Size().Y*SY*0.5 + PY
	r.MaxY = T.Size().Y*SY*0.5 + PY
	return r
}

func (n *Node) GetRect(node INode, Scale Vec3, Pos Vec3) *Rect {
	if n.MGetRect != nil {
		return n.MGetRect(node, Scale, Pos)
	}
	return nil
}

func (n *Node) AddCompnent(F CompnentFunc) ICompnent {
	v, k := F(true, n)
	v.CSetNode(n)
	if n.compnents == nil {
		n.compnents = make(map[string]ICompnent)
	}
	n.compnents[k] = v
	return v
}

func (n *Node) GetCompnent(F CompnentFunc) ICompnent {
	_, k := F(false, n)
	if n.compnents != nil {
		return n.compnents[k]
	}
	return nil

}

func (n *Node) GetMe() interface{} {
	return n.Me
}

func (n *Node) GetNode() *Node {
	return n
}

func (n *Node) GetLayer() uint32 {
	return n.NodeLayer
}
func (n *Node) SetLayer(layer uint32) {
	n.NodeLayer = layer
}

func (n *Node) SetParent(PNode INode) {
	n.ParentNode = PNode
}

func (n *Node) Parent() INode {

	return n.ParentNode
}
func (n *Node) Childrens() *ACArrayList {
	return &n.ChildrenNodes
}

func (n *Node) GetTransfrom() ITransfrom {
	return n.ITransfrom
}

func (n *Node) SetTransfrom(it ITransfrom) {
	n.ITransfrom = it
}

func (n *Node) Render() {

}

func (n *Node) GetRender() IRenderer {
	return n.NodeRender
}

func (n *Node) BeforeRender() {

}

func (n *Node) AfterRender() {

}

func (n *Node) RemoveChild(node INode) {
	n.Childrens().Remove(node)
	node.GetNode().ParentNode = nil
}
func (n *Node) RemoveChildAt(Index int) {
	n.Childrens().I(Index).(INode).SetParent(nil)
	n.ChildrenNodes.RemoveByIndex(Index)
}

func (n *Node) DeleteNode(node INode) {
	n.RemoveChild(node)
	n._Destroy()
}

func (n *Node) _Destroy() {
	if n.Childrens() != nil && n.Childrens().ArrData != nil {
		for i := 0; i < n.Childrens().GetSize(); i++ {
			n.Childrens().I(i).(INode).Destroy()
		}
	}
	n.Destroy()
}
func (n *Node) Destroy() {

}

func AddChild(_P, _C INode) {
	_C.SetParent(_P)
	mcs := _P.Childrens()
	if _P.GetLayer() != 0 {
		_C.SetLayer(_P.GetLayer())
	}

	if mcs.ArrData == nil {
		_P.GetNode().ChildrenNodes = New_ArrayList(2)
	}
	_P.GetNode().ChildrenNodes.Add(_C)
}
